﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CutAways.Modeling
{
	public class MaterialLoader
	{
		public Material[] LoadFromFile(string filename)
		{
			if (filename == null || !File.Exists(filename))
				throw new ModelLoadingException("Material file can't be found.");

			List<Material> materials = new List<Material>();
			TextReader input = File.OpenText(filename);
			
			try
			{
				Material currentMaterial = null;
				for (string line = input.ReadLine(); line != null; line = input.ReadLine())
				{
					line = line.Trim();
					if (line == string.Empty || line[0] == '#') // komentar nebo prazdnej radek
						continue;
					string[] parts = line.Split(' ');

					switch (parts[0])
					{
						case "newmtl": // novy material
							if (currentMaterial != null)
								materials.Add(currentMaterial);
							currentMaterial = new Material();
                            currentMaterial.Name = line.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries)[1];
							break;
						case "Ka": // Ambient light
							currentMaterial.Ambient[0] = float.Parse(parts[1]);
							currentMaterial.Ambient[1] = float.Parse(parts[2]);
							currentMaterial.Ambient[2] = float.Parse(parts[3]);
							currentMaterial.Ambient[3] = 1f;
							break;
						case "Kd": // Diffuse
							currentMaterial.Diffuse[0] = float.Parse(parts[1]);
							currentMaterial.Diffuse[1] = float.Parse(parts[2]);
							currentMaterial.Diffuse[2] = float.Parse(parts[3]);
							currentMaterial.Diffuse[3] = 1f;
							break;
						case "Ks": // Specular
							currentMaterial.Specular[0] = float.Parse(parts[1]);
							currentMaterial.Specular[1] = float.Parse(parts[2]);
							currentMaterial.Specular[2] = float.Parse(parts[3]);
							currentMaterial.Specular[3] = 1f;
							break;
						case "d": // Alpha
						case "Tr":
							currentMaterial.Alpha = float.Parse(parts[1]);
							break;
						case "Ns": // Shininess
							currentMaterial.Shininess = float.Parse(parts[1]);
							break;
						case "map_Kd": // textura
							currentMaterial.TextureIndex = new TextureLoader().LoadTextureFromFile(Path.IsPathRooted(parts[1]) ? parts[1] : Path.Combine(Path.GetDirectoryName(filename), parts[1]));
							break;
						case "illum":
						default:
							break;
					}
				}
				if (currentMaterial != null)
					materials.Add(currentMaterial);
			}
			finally
			{
				input.Close();
			}

			return materials.ToArray();
		}
	}
}
